package com.feng.test.zip;

/**
 * @author HuangSuip
 */

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 将文件打包成ZIP压缩文件
 *
 * @author LanP
 * @since 2012-3-1 15:47
 */
public final class FileToZip {

    private FileToZip() {

    }

    public static ByteArrayOutputStream fileToZip(String sourceFilePath, String zipFilePath, String fileName) {
        boolean flag = false;
        File sourceFile = new File(sourceFilePath);
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        FileOutputStream fos = null;
        ZipOutputStream zos = null;
        ByteArrayOutputStream baos = null;
        DataOutputStream to = null;

        try {
            File zipFile = new File(zipFilePath + "/" + fileName + ".zip");
            File[] sourceFiles = sourceFile.listFiles();
            fos = new FileOutputStream(zipFile);
            zos = new ZipOutputStream(new BufferedOutputStream(fos));
            baos = new ByteArrayOutputStream();
            //zos = new ZipOutputStream(baos);

            byte[] bufs = new byte[1024 * 10];

            for (int i = 0; i < sourceFiles.length; i++) {
                if (sourceFiles[i].isDirectory()) {
                    System.out.println("is ditectory");
                    File[] files = sourceFiles[i].getAbsoluteFile().listFiles();
                    for (File file : files) {
                        zos.putNextEntry(new ZipEntry(sourceFiles[i].getName() + "/" + file.getName()));
                        fis = new FileInputStream(file);
                        bis = new BufferedInputStream(fis, 1024 * 10);
                        int read = 0;
                        while ((read = bis.read(bufs, 0, 1024 * 10)) != -1) {
                            zos.write(bufs, 0, read);
                        }
                    }
                } else {
                    // 创建ZIP实体,并添加进压缩包
                    ZipEntry zipEntry = new ZipEntry(sourceFiles[i].getName());
                    zos.putNextEntry(zipEntry);
                    // 读取待压缩的文件并写进压缩包里
                    fis = new FileInputStream(sourceFiles[i]);
                    bis = new BufferedInputStream(fis, 1024 * 10);
                    int read = 0;
                    while ((read = bis.read(bufs, 0, 1024 * 10)) != -1) {
                        zos.write(bufs, 0, read);
                    }
                }
            }
            zos.flush();
            zos.finish();

            baos.writeTo(fos);
            baos.flush();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally {
            // 关闭流
            try {
                if (null != zos) {zos.close();}
                if (null != baos) {baos.close();}
                if (null != fos) {fos.close();}
                if (null != bis) {bis.close();}
            } catch (IOException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }
        }
        return baos;
    }

    public static boolean zipArchive(String sourceFilePath, OutputStream output) {
        boolean flag = false;
        File sourceFile = new File(sourceFilePath);
        FileInputStream fis = null;
        ZipOutputStream zos = null;

        if (!sourceFile.exists()) {
            System.out.println(">>>>>> 待压缩的文件目录：" + sourceFilePath + " 不存在. <<<<<<");
        } else {
            try {
                File[] sourceFiles = sourceFile.listFiles();
                if (null == sourceFiles || sourceFiles.length < 1) {
                    System.out.println(">>>>>> 待压缩的文件目录：" + sourceFilePath + " 里面不存在文件,无需压缩. <<<<<<");
                } else {
                    zos = new ZipOutputStream(output);
                    byte[] bufs = new byte[1024 * 10];
                    for (int i = 0; i < sourceFiles.length; i++) {
                        if (sourceFiles[i].isDirectory()) {
                            System.out.println("is ditectory");
                            File[] files = sourceFiles[i].getAbsoluteFile().listFiles();
                            for (File file : files) {
                                zos.putNextEntry(new ZipEntry(sourceFiles[i].getName() + "/" + file.getName()));
                                fis = new FileInputStream(file);
                                BufferedInputStream bis = new BufferedInputStream(fis, 1024 * 10);
                                int read = 0;
                                while ((read = bis.read(bufs, 0, 1024 * 10)) != -1) {
                                    zos.write(bufs, 0, read);
                                }
                            }
                        } else {
                            // 创建ZIP实体,并添加进压缩包
                            ZipEntry zipEntry = new ZipEntry("media/"+sourceFiles[i].getName());
                            zos.putNextEntry(zipEntry);
                            // 读取待压缩的文件并写进压缩包里
                            fis = new FileInputStream(sourceFiles[i]);
                            BufferedInputStream bis = new BufferedInputStream(fis, 1024 * 10);
                            int read = 0;
                            while ((read = bis.read(bufs, 0, 1024 * 10)) != -1) {
                                zos.write(bufs, 0, read);
                            }
                        }
                    }
                    zos.flush();
                    flag = true;
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            } catch (IOException e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            } finally {
                // 关闭流
                try {
                    if (null != zos) {zos.close();}
                } catch (IOException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            }
        }

        return flag;
    }

    /**
     * 将文件打包成ZIP压缩文件,main方法测试
     *
     * @param args
     */
    public static void main(String[] args) throws Exception {
        String sourceFilePath = "E:\\temp";
        String zipFilePath = "E:";
        String fileName = "myTest";
        String fullName = zipFilePath + "\\" + fileName + "-B.zip";
        try  {
            FileOutputStream fs = new FileOutputStream(fullName);
            FileToZip.fileToZip(sourceFilePath, zipFilePath, fileName).writeTo(fs);
        }catch (Exception e){

        }

        try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
            boolean flag = FileToZip.zipArchive(sourceFilePath, outputStream);
            try (FileOutputStream fs = new FileOutputStream(fullName)) {
                outputStream.writeTo(fs);
            }
            if (flag) {
                System.out.println(">>>>>> 文件打包成功. <<<<<<");
            } else {
                System.out.println(">>>>>> 文件打包失败. <<<<<<");
            }
        }
    }
}
